package com.qall.util;


import org.apache.http.Consts;
import org.apache.http.HttpEntity;

import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.core.env.Environment;
import org.springframework.util.Assert;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.*;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


public class HttpsUtil {


    public static String post(String url, String host, Map<String, String> body, int port, Map<String, String> params, Map<String, String> header) throws IOException {
        // 创建 CloseableHttpClient 对象
        SSLConnectionSocketFactory socketFactory = null;
        try {
            socketFactory = getSocketFactory();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (KeyStoreException e) {
            e.printStackTrace();
        } catch (CertificateException e) {
            e.printStackTrace();
        } catch (UnrecoverableKeyException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
        CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();

        // 指定请求的 URL 并创建 HttpPost 对象
        HttpPost httppost = new HttpPost(url);
        // 设置请求通过的代理
        httppost.setConfig(RequestConfig.custom().setProxy(new HttpHost(host, port)).build());
        HttpEntity entity;

        // 设置请求的 ContentType 为 application/x-www-form-urlencoded
//        httppost.addHeader(HttpHeaders.CONTENT_TYPE, "application/x-www-form-urlencoded");
        header.entrySet().forEach(x -> {
            httppost.addHeader(x.getKey(),x.getValue());
        });
        // 构建 POST 的内容
        List<BasicNameValuePair> nvps = new ArrayList<>();
        body.entrySet().forEach(x -> nvps.add(new BasicNameValuePair(x.getKey(), x.getValue())));
        entity = new UrlEncodedFormEntity(nvps, Consts.UTF_8);
        httppost.setEntity(entity);

        CloseableHttpResponse response = null;

        StringBuilder builder = new StringBuilder();
        try {
            // 发送请求
            response = httpclient.execute(httppost);


            InputStream inputStream = response.getEntity().getContent();

            byte[] bytes = new byte[1024];
            while (inputStream.read(bytes) != -1) {
                String tmp = new String(bytes);
                builder.append(tmp);
            }
            // 获取响应内容
            HttpEntity entity1 = response.getEntity();

            System.out.println(EntityUtils.toString(entity1));
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (null != response) {
                response.close();
            }
            if (null != httpclient) {
                httpclient.close();
            }
        }
        return builder.toString();
    }


    public static String get(String url) {
        SSLConnectionSocketFactory socketFactory = null;
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(socketFactory).build();
        CloseableHttpResponse response = null;
        BufferedReader in = null;
        String result = "";
        try {
            HttpGet httpGet = new HttpGet(url);
            RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(30000).setConnectionRequestTimeout(30000).setSocketTimeout(30000).build();
            httpGet.setConfig(requestConfig);
            httpGet.setConfig(requestConfig);
            httpGet.addHeader("Content-type", "application/json; charset=utf-8");
            httpGet.setHeader("Accept", "application/json");
            response = httpClient.execute(httpGet);
            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer("");
            String line = "";
            String NL = System.getProperty("line.separator");
            while ((line = in.readLine()) != null) {
                sb.append(line + NL);
            }
            in.close();
            result = sb.toString();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (null != response) {
                    response.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return result;

    }

        private static TrustManager getTrustManagers() {
        return new X509TrustManager() {
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            public void checkClientTrusted(X509Certificate[] certs, String authType) {
            }

            public void checkServerTrusted(X509Certificate[] certs, String authType) {
            }
        };
    }

    private static SSLConnectionSocketFactory getSocketFactory() throws IOException, KeyStoreException, CertificateException, UnrecoverableKeyException, KeyManagementException {
        SSLContext sslContext;
        try {
            Environment environment = BeanUtils.instantiateClass(Environment.class);
            String keyPath = environment.getProperty("https.p12-key-path");
            String password = environment.getProperty("https.p12-password");
            Assert.notNull(keyPath, "https.p12-key-path not config");
            Assert.notNull(password, "https.p12-password not config");

            // keyStore 用来存放客户端证书
            KeyStore keyStore = KeyStore.getInstance("PKCS12");
            FileInputStream instream = new FileInputStream(keyPath);
            try {
                keyStore.load(instream, password.toCharArray());
            } finally {
                instream.close();
            }

            // 加载客户端证书，并设置HTTPS的安全协议为 TLSv1.2
            sslContext = SSLContexts.custom().loadKeyMaterial(keyStore, password.toCharArray()).useProtocol("TLSv1.2").build();
        } catch (NoSuchAlgorithmException | UnrecoverableKeyException e) {
            return null;
        }
        try {
            sslContext.init(null, new TrustManager[]{getTrustManagers()}, new java.security.SecureRandom());
        } catch (KeyManagementException e) {
            return null;
        }
        return new SSLConnectionSocketFactory(sslContext);
    }
}
